<?php
/***********************************************************************
 * @package    	IvanEngine
 * @subpackage 	Core
 * @author     	Ivan <ivanzx@msn.com>
 * @created    	2010-05-19
 ***********************************************************************/
if(defined("IVANENGINE_CORE_VALIDATOR_OR"))
	die("Redefinition macro in :".__FILE__."(".__LINE__.")");
define("IVANENGINE_CORE_VALIDATOR_OR", true);

require_once (dirname(__FILE__).'/ValidatorBase.php');

class CValidatorOr extends CValidatorBase
{
	protected $m_validators = array();
	
	public function __construct($validators = null, $options = array(), $messages = array())
  	{
	    if ($validators instanceof CValidatorBase)
	    {
	      	$this->AddValidator($validators);
	    }
	    else if (is_array($validators))
	    {
	      	foreach ($validators as $validator)
	      	{
	        	$this->AddValidator($validator);
	      	}
	    }
	    else if (!is_null($validators))
	    {
	      throw new CExceptionInvalidArgument('CValidatorOr constructor takes a CValidatorBase object, or a CValidatorBase array.');
	    }
	    
	    parent::__construct($options, $messages);
  	}
  
	protected function Initialize($options = array(), $messages = array())
  	{
  		parent::Initialize($options, $messages);
		$this->SetMessage(self::NM_Invalid, null);
  	}
  	
	protected function DoVerify($value) 
	{
		$errors = array();
	    foreach ($this->m_validators as $validator)
	    {
	      	try
	      	{
	        	return $validator->clean($value);
	      	}
	      	catch (CExceptionValidator $e)
	      	{
	        	$errors[] = $e;
	      	}
	    }
	
	    if ($this->GetMessage(self::NM_Invalid))
	    {
	      	throw new CExceptionValidator($this, self::NM_Invalid, array('value' => $value));
	    }
	
	    throw new CExceptionValidatorMap($this, $errors);
	}

  	public function addValidator(sfValidatorBase $validator)
  	{
    	$this->m_validators[] = $validator;
  	}

  	public function GetValidators()
  	{
    	return $this->m_validators;
  	}

  	public function AsString($indent = 0)
  	{
	    $validators = '';
	    for ($i = 0, $max = count($this->m_validators); $i < $max; $i++)
	    {
	      	$validators .= "\n".$this->m_validators[$i]->AsString($indent + 2)."\n";
	
	      	if ($i < $max - 1)
	      	{
	        	$validators .= str_repeat(' ', $indent + 2).'or';
	      	}
	
	      	if ($i == $max - 2)
	      	{
		        $options = $this->GetOptionsWithoutDefaults();
		        $messages = $this->GetMessagesWithoutDefaults();
		
		        if ($options || $messages)
		        {
		          	$validators .= sprintf('(%s%s)',
		            	$options ? $options : ($messages ? '{}' : ''),
		            	$messages ? ', '.$messages : ''
		          );
		        }
	      	}
	    }
	
	    return sprintf("%s(%s%s)", str_repeat(' ', $indent), $validators, str_repeat(' ', $indent));
  	}
}

?>